package cn.mw.cmdb.service.impl;


import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.ModelInfo;
import cn.mw.cmdb.entity.PropertyInfo;
import cn.mw.cmdb.exception.CompoundException;
import cn.mw.microMonitorCommon.annotation.aop.ApplicationContextProvider;
import cn.mw.microMonitorCommon.annotation.scan.StartFeatureFlowScan;
import cn.mw.microMonitorCommon.annotation.service.CmdbService;
import cn.mw.microMonitorCommon.entity.FeatureNeedObject;
import cn.mw.microMonitorCommon.entity.FlowableEventGroupChineseVb;
import cn.mw.microMonitorCommon.entity.TestObject;
import cn.mw.microMonitorCommon.util.StringUtil;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.reflect.TypeToken;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.*;
import java.util.*;

import static cn.mw.cmdb.entity.InstanceInfo.SearchPrefix;
import static cn.mw.cmdb.util.ValConvertUtil.booleanValueConvert;
import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;
import static cn.mw.microMonitorCommon.constant.ProcdedConstant.INSTANCEID_KEY;
import static cn.mw.microMonitorCommon.constant.ProcdedConstant.USERS;
import static cn.mw.microMonitorCommon.util.ListMapObjUtils.beanToMap;

/**
 * @author lumingming
 * @createTime 20231011 15:50
 * @description
 */
@DubboService
@Service
@Slf4j
public class CmdbServiceImpl implements CmdbService {
    private CmdbServiceManage cmdbServiceManage;

    public CmdbServiceImpl(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    //执行Activities回调的方法
    @Override
    public String runActivite(TestObject testObject) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException {
        Method method = null;
        Class<?> clazz = Class.forName(testObject.getObjectClassImp());
        String className = StringUtil.getInstance().lowerFirstCapse(clazz.getSimpleName());
        Object bean = (Object) ApplicationContextProvider.getBean(className);
        Object[] kill;
        List<Class<?>> classes = new ArrayList<>();
        for (Object o : testObject.getArg()) {
            classes.add(o.getClass());
        }

        Method methodref = null;
        for (Method methodrSin : clazz.getDeclaredMethods()) {
            if (methodrSin.getName().equals(testObject.getActionName())) {
                methodref = methodrSin;
            }
        }


        Parameter[] parameters = methodref.getParameters();
        List<Object> args = testObject.getArg();
        //返回成Map<String,String>类型
        Gson gson = new Gson();
        Map<String, String> map = JSONObject.parseObject(args.get(0).toString(), Map.class);
        if (args.size() > 1) {
            map = JSONObject.parseObject(args.get(1).toString(), Map.class);
        }

        List<Object> objectList = new ArrayList<>();
        String instanceId = "";
        for (Parameter p : parameters) {
            if (getBasicLong(p.getType().toString()) > 0) {
                Object o = getValueObject(map.get("processId"), getBasicLong(p.getType().toString()));
                objectList.add(o);
            } else if (p.getType().getName().equals("java.util.Map")) {
                Map<String, Object> mapkey = new HashMap<>();
                Type type = new TypeToken<Map<String, String>>() {
                }.getType();
                mapkey = gson.fromJson(args.get(0).toString(), type);
                Map<String, Object> mapkey2 = new HashMap<>(mapkey);
                instanceId = mapkey.get(INSTANCEID_KEY).toString();
                dealMap(mapkey2);
                objectList.add(mapkey2);
            } else if (objectList.size() == 1) {
                objectList.add(instanceId);
            } else {
                Class<?> shuxing = Class.forName(String.valueOf(p.getType()).replace("class ", ""));
                Class<?> superClass = shuxing.getSuperclass();
                // 创建类的实例
                Object instance = shuxing.getDeclaredConstructor().newInstance();
                for (String k : map.keySet()) {
                    Field nameField = null;
                    try{
                        nameField = shuxing.getDeclaredField(k);
                    }catch (Exception e){
                        try{
                            nameField = superClass.getDeclaredField(k);
                        }catch (Exception ex){

                        }

                    }
                    try {
                        nameField.setAccessible(true);
                        Object o = new Object();
                        if (getBasicLong(nameField.getType().toString().replace("class ", "")) > 0) {
                            o = getValueObject(map.get(k), getBasicLong(nameField.getType().toString().replace("class ", "")));
                        }else {
                            o = getValueObject(JSONObject.toJSONString(map.get(k)), getBasicLong(nameField.getType().toString().replace("class ", "")));
                        }
                       nameField.set(instance, o);
                    } catch (Exception e) {
                        log.error("转换报错：{}",e);

                    }
                }
                objectList.add(instance);
            }
        }
        Class<?>[] argArray = new Class[objectList.size()];
        for (int i = 0; i < objectList.size(); i++) {
            if (objectList.get(i).getClass().getName().contains("HashMap")) {
                argArray[i] = Map.class;
            } else {
                argArray[i] = objectList.get(i).getClass();
            }
        } // 调用方法并传递参数列表 someMethod(argArray);

        method = ReflectionUtils.findMethod(bean.getClass(), testObject.getActionName(), argArray);
        Object res = ReflectionUtils.invokeMethod(method, bean, objectList.toArray());

        /*  System.out.println("获取"+gson.toJson(res));*/
        /*return res;*/
        return gson.toJson(res);
    }

    private Object getValueObject(String s, Integer i) {
        Object o = null;
        switch (i) {
            case 1:
                o = s;
                break;
            case 2:
                o = Integer.valueOf(s);
                break;
            case 3:
                o = Boolean.valueOf(s);
                break;
            case 4:
                o = Float.valueOf(s);
                break;
            case 5:
                o = Long.valueOf(s);
                break;
            case 6:
                o = new Date();
                break;
            case 7:
                o = Double.valueOf(s);
                break;
            case -3:
                try{
                    if(s.startsWith("[[") ){
                        o = stringToListList(s);
                    }else {
                        o = parseStringToList(s);
                    }

                }catch (Exception e){

                }
                break;
            case -2:
                o = JSONObject.parseObject(s, Map.class);
                break;
        }
        return o;
    }

    public static List<Long> parseStringToList(String input) {
        List<Long> list = new ArrayList<>();
        // 移除字符串中的首尾括号，然后使用逗号分割字符串
        String[] parts = input.substring(1, input.length() - 1).split(",");
        for (String part : parts) {
            // 将分割出的字符串转换为整数并添加到列表中
            list.add(Long.parseLong(part.trim()));
        }
        return list;
    }

    public static List<List<Long>> stringToListList(String str) {
        List<List<Long>> list = new ArrayList<>();
        String[] parts = str.substring(2, str.length() - 2).split("\\],\\[");
        for (String part : parts) {
            list.add(parseStringToList("[" + part + "]"));
        }
        return list;
    }

    //判断是否为基础属性
    private Integer getBasicLong(String aClass) {
        if (aClass.contains(String.class.getName())) {
            return 1;
        } else if (aClass.contains(Integer.class.getName())) {
            return 2;
        } else if (aClass.contains(Boolean.class.getName())) {
            return 3;
        } else if (aClass.contains(Float.class.getName())) {
            return 4;
        } else if (aClass.contains(Long.class.getName())) {
            return 5;
        } else if (aClass.contains(Date.class.getName())) {
            return 6;
        } else if (aClass.contains(Double.class.getName())) {
            return 7;
        } else if (aClass.contains(List.class.getName())) {
        return -3;
        } else if (aClass.contains(Map.class.getName())) {
            return -2;
        } else {
            return -1;
        }

    }

    //当流程引擎模块被迫重启的时候/或者获取各模块的存活状况时
    @Override
    public FlowableEventGroupChineseVb getMyselfObject() {
        return StartFeatureFlowScan.flowableEventGroupChineseVb;
    }


    //更具流程的参数返回是否纳入流程
    @Override
    public Boolean judgeActiviti(Object objectStr) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(strValueConvert(objectStr)).get("paramJson");
        if(null!=jsonNode){
            String instanceInfoText = jsonNode.asText();
            List<Object> list = objectMapper.readValue(instanceInfoText, List.class);
            List<InstanceInfo> instanceInfoList = list.stream().map(item ->
                            JSONObject.parseObject(JSON.toJSONString(item), InstanceInfo.class))
                    .toList();
            for (InstanceInfo instanceInfo : instanceInfoList) {
                if (instanceInfo != null) {
                    String modelId = instanceInfo.getModelId();
                    CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                    ModelInfo modelInfo = modelService.doSelectById(modelId);
                    if (modelInfo.getEnableProManage()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //获取流程节点结构
    @Override
    public FeatureNeedObject getFeatureNeedObject(List<Object> objectList) {
        FeatureNeedObject featureNeedObject = new FeatureNeedObject();
        try {
            if (CollectionUtils.isNotEmpty(objectList)) {
                Map map = new HashMap();
                Map<String, PropertyInfo> propertyMap = new HashMap<>();
                for (Object o : objectList) {
                    //调用cmdb实例方法的参数
                    if (o != null && o instanceof Map) {
                        Gson gson = new Gson();
                        InstanceInfo instanceParam = JSONObject.parseObject(gson.toJson(o), InstanceInfo.class);
                        map = beanToMap(instanceParam);
                        Map m = (Map) map.get(SearchPrefix);
                        map.putAll(m);

                        String modelId = instanceParam.getModelId();
                        CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                        ModelInfo modelInfo = modelService.doSelectById(modelId);
                        propertyMap = modelInfo.getPropertyInfoById();
                    }
                }

                Map<String, PropertyInfo> finalPropertyInfo = propertyMap;
                map.forEach((k, v) -> {
                    if (finalPropertyInfo != null && finalPropertyInfo.containsKey(k)) {
                        String propertyId = strValueConvert(k);
                        PropertyInfo propertyInfo = finalPropertyInfo.get(k);
                        //中文名称
                        String descName = propertyInfo.getName();
                        //属性类型
                        String type = propertyInfo.getPropertyType().id;
                        //是否纳入流程属性
                        Boolean enableProManage = booleanValueConvert(propertyInfo.getEnableProManage());
                        featureNeedObject.addAttribute(type, propertyId, descName, enableProManage, false, null);
                    }
                });
            }
        } catch (Exception e) {
            throw new CompoundException();
        }
        return featureNeedObject;
    }

    private void dealMap(Map<String, Object> map){
        if (map.containsKey(USERS)) {
            List<Long> users = new ArrayList<>();
            if (!StringUtils.isBlank(map.get(USERS).toString())) {
                Long user = Long.parseLong(map.get(USERS).toString());
                users.add(user);
                map.put(USERS, users);
            }
        }



    }

}
